home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Camelot / Camelot 074 (1990-04)(Swedish User Group of Amiga)(SE)(PD)[WB].zip / Camelot 074 (1990-04)(Swedish User Group of Amiga)(SE)(PD)[WB].adf / A68k / Opcodes.c < prev    next >
C/C++ Source or Header  |  1990-04-23  |  9KB  |  295 lines

  1. /*------------------------------------------------------------------*/
  2. /*                                    */
  3. /*            MC68000 Cross Assembler                */
  4. /*                                    */
  5. /*        Copyright (c) 1985 by Brian R. Anderson            */
  6. /*                                    */
  7. /*         Opcode table and scan routine - October 22, 1989        */
  8. /*                                    */
  9. /*   This program may be copied for personal, non-commercial use    */
  10. /*   only, provided that the above copyright notice is included        */
  11. /*   on all copies of the source code.  Copying for any other use   */
  12. /*   without the consent of the author is prohibited.            */
  13. /*                                    */
  14. /*------------------------------------------------------------------*/
  15. /*                                    */
  16. /*        Originally published (in Modula-2) in            */
  17. /*        Dr. Dobb's Journal, April, May, and June 1986.        */
  18. /*                                    */
  19. /*     AmigaDOS conversion copyright 1989 by Charlie Gibbs.        */
  20. /*                                    */
  21. /*------------------------------------------------------------------*/
  22.  
  23. #include <stdio.h>
  24. #include "A68kdef.h"
  25. #include "A68kglb.h"
  26.  
  27. /* Functions */
  28. extern int  LineParts(), ObjDir();
  29. extern int  GetInstModeSize(), GetMultReg(), CountNest();
  30. extern int  ReadSymTab(), GetArgs(), GetAReg(), OpenIncl();
  31. extern long AddrBndW(), AddrBndL(), GetValue(), CalcValue();
  32. extern char *AddName(), *GetField();
  33. extern struct SymTab *NextSym();
  34. extern struct SymTab **HashIt();
  35.  
  36.  
  37.  
  38. int Instructions (loc) int loc;
  39. /* Looks up opcode and addressing mode bit patterns
  40.    If the opcode corresponds to an executable instruction,
  41.      returns TRUE with the following fields set up:
  42.     Op       - operation code bits
  43.     AdrModeA - addressing mode bits
  44.     AdrModeB - more addressing mode bits
  45.     Dir      - None
  46.    If the opcode corresponds to a directive (AdrModeA in the table
  47.      is 0xFFFF), returns TRUE with the following fields set up:
  48.     Op       - 0
  49.     AdrModeA - 0
  50.     AdrModeB - 0
  51.     Dir      - the appropriate directive value
  52.    If not found, returns FALSE with all the above fields set to zero.
  53.  
  54.    NOTE: The binary search doesn't use strcmp because this function
  55.     returns incorrect values under MS-DOS Lattice 2.12.              */
  56. {
  57.     static int maxinst = 0;        /* Size of opcode table */
  58.     static int limits['Z'-'A'+2];    /* Table limits by first letter */
  59.     register char *i, *j;
  60.     register int  lower, upper, mid;    /* Binary search controls */
  61.  
  62. /* Opcode table */
  63.  
  64.     struct OpTab {
  65.     char Mnem[8];    /* Instruction mnemonic */
  66.     int  OpBits;    /* Op code bits */
  67.     int  AMA;    /* Address mode bits */
  68.     int  AMB;    /* More address mode bits */
  69.     };
  70.  
  71.     static struct OpTab MnemTab[] = {
  72.     "=",     0,      0xFFFF, Equ,
  73.     "ABCD",  0xC100, Rx911 | RegMem3 | Ry02, 0,
  74.     "ADD",   0xD000, OpM68D, EA05y,
  75.     "ADDA",  0xD000, OpM68A, EA05a,
  76.     "ADDI",  0x0600, 0, Size67 | EA05e | Exten,
  77.     "ADDQ",  0x5000, Data911, Size67 | EA05d,
  78.     "ADDX",  0xD100, Rx911 | RegMem3 | Ry02, Size67,
  79.     "AND",   0xC000, OpM68D, EA05x,
  80.     "ANDI",  0x0200, 0, Size67 | EA05e | Exten,
  81.     "ASL",   0xE100, CntR911, 0,
  82.     "ASR",   0xE000, CntR911, 0,
  83.     "BCC",   0x6400, Brnch, 0,
  84.     "BCHG",  0x0040, 0, EA05e | Exten | Bit811,
  85.     "BCLR",  0x0080, 0, EA05e | Exten | Bit811,
  86.     "BCS",   0x6500, Brnch, 0,
  87.     "BEQ",   0x6700, Brnch, 0,
  88.     "BGE",   0x6C00, Brnch, 0,
  89.     "BGT",   0x6E00, Brnch, 0,
  90.     "BHI",   0x6200, Brnch, 0,
  91.     "BLE",   0x6F00, Brnch, 0,
  92.     "BLS",   0x6300, Brnch, 0,
  93.     "BLT",   0x6D00, Brnch, 0,
  94.     "BMI",   0x6B00, Brnch, 0,
  95.     "BNE",   0x6600, Brnch, 0,
  96.     "BPL",   0x6A00, Brnch, 0,
  97.     "BRA",   0x6000, Brnch, 0,
  98.     "BSET",  0x00C0, 0, EA05e | Exten | Bit811,
  99.     "BSR",   0x6100, Brnch, 0,
  100.     "BSS",   0,      0xFFFF, BSS,
  101.     "BTST",  0x0000, 0, EA05c | Exten | Bit811,
  102.     "BVC",   0x6800, Brnch, 0,
  103.     "BVS",   0x6900, Brnch, 0,
  104.     "CHK",   0x4180, Rx911, EA05b,
  105.     "CLR",   0x4200, 0, Size67 | EA05e,
  106.     "CMP",   0xB000, OpM68C, EA05a,
  107.     "CMPA",  0xB000, OpM68A, EA05a,
  108.     "CMPI",  0x0C00, 0, Size67 | EA05e | Exten,
  109.     "CMPM",  0xB108, Rx911 | Ry02, Size67,
  110.     "CNOP",  0,      0xFFFF, Cnop,
  111.     "CODE",  0,      0xFFFF, CSeg,
  112.     "CSEG",  0,      0xFFFF, CSeg,
  113.     "DATA",  0,      0xFFFF, DSeg,
  114.     "DBCC",  0x54C8, DecBr, 0,
  115.     "DBCS",  0x55C8, DecBr, 0,
  116.     "DBEQ",  0x57C8, DecBr, 0,
  117.     "DBF",   0x51C8, DecBr, 0,
  118.     "DBGE",  0x5CC8, DecBr, 0,
  119.     "DBGT",  0x5EC8, DecBr, 0,
  120.     "DBHI",  0x52C8, DecBr, 0,
  121.     "DBLE",  0x5FC8, DecBr, 0,
  122.     "DBLS",  0x53C8, DecBr, 0,
  123.     "DBLT",  0x5DC8, DecBr, 0,
  124.     "DBMI",  0x5BC8, DecBr, 0,
  125.     "DBNE",  0x56C8, DecBr, 0,
  126.     "DBPL",  0x5AC8, DecBr, 0,
  127.     "DBRA",  0x51C8, DecBr, 0,
  128.     "DBT",   0x50C8, DecBr, 0,
  129.     "DBVC",  0x58C8, DecBr, 0,
  130.     "DBVS",  0x59C8, DecBr, 0,
  131.     "DC",    0,      0xFFFF, DC,
  132.     "DCB",   0,      0xFFFF, DCB,
  133.     "DIVS",  0x81C0, Rx911, EA05b,
  134.     "DIVU",  0x80C0, Rx911, EA05b,
  135.     "DS",    0,      0xFFFF, DS,
  136.     "DSEG",  0,      0xFFFF, DSeg,
  137.     "END",   0,      0xFFFF, End,
  138.     "ENDC",  0,      0xFFFF, EndC,
  139.     "ENDIF", 0,      0xFFFF, EndC,
  140.     "EOR",   0xB000, OpM68X, EA05e,
  141.     "EORI",  0x0A00, 0, Size67 | EA05e | Exten,
  142.     "EQU",   0,      0xFFFF, Equ,
  143.     "EQUR",  0,      0xFFFF, Equr,
  144.     "EVEN",  0,      0xFFFF, Even,
  145.     "EXG",   0xC100, OpM37, 0,
  146.     "EXT",   0x4800, OpM68S, 0,
  147.     "FAR",   0,      0xFFFF, Far,
  148.     "IDNT",  0,      0xFFFF, Idnt,
  149.     "IFC",   0,      0xFFFF, IfC,
  150.     "IFD",   0,      0xFFFF, IfD,
  151.     "IFEQ",  0,      0xFFFF, IfEQ,
  152.     "IFGE",  0,      0xFFFF, IfGE,
  153.     "IFGT",  0,      0xFFFF, IfGT,
  154.     "IFLE",  0,      0xFFFF, IfLE,
  155.     "IFLT",  0,      0xFFFF, IfLT,
  156.     "IFNC",  0,      0xFFFF, IfNC,
  157.     "IFND",  0,      0xFFFF, IfND,
  158.     "IFNE",  0,      0xFFFF, IfNE,
  159.     "ILLEGAL", 0x4AFC, 0, 0,
  160.     "INCLUDE", 0,    0xFFFF, Include,
  161.     "JMP",   0x4EC0, 0, EA05f,
  162.     "JSR",   0x4E80, 0, EA05f,
  163.     "LEA",   0x41C0, Rx911, EA05f,
  164.     "LINK",  0x4E50, Ry02, Exten,
  165.     "LIST",  0,      0xFFFF, DoList,
  166.     "LSL",   0xE308, CntR911, 0,
  167.     "LSR",   0xE208, CntR911, 0,
  168.     "MACRO", 0,      0xFFFF, Macro,
  169.     "MOVE",  0x0000, 0, Sz1213A | EA611,
  170.     "MOVEA", 0x0040, Rx911, Sz1213 | EA05a,
  171.     "MOVEM", 0x4880, 0, Size6 | EA05z | Exten,
  172.     "MOVEP", 0x0008, OpM68R, Exten,
  173.     "MOVEQ", 0x7000, Data07, 0,
  174.     "MULS",  0xC1C0, Rx911, EA05b,
  175.     "MULU",  0xC0C0, Rx911, EA05b,
  176.     "NBCD",  0x4800, 0, EA05e,
  177.     "NEAR",  0,      0xFFFF, Near,
  178.     "NEG",   0x4400, 0, Size67 | EA05e,
  179.     "NEGX",  0x4000, 0, Size67 | EA05e,
  180.     "NOL",   0,      0xFFFF, NoList,
  181.     "NOLIST",0,      0xFFFF, NoList,
  182.     "NOP",   0x4E71, 0, 0,
  183.     "NOT",   0x4600, 0, Size67 | EA05e,
  184.     "OR",    0x8000, OpM68D, EA05x,
  185.     "ORG",   0,      0xFFFF, Org,
  186.     "ORI",   0x0000, 0, Size67 | EA05e | Exten,
  187.     "PAGE",  0,      0xFFFF, Page,
  188.     "PEA",   0x4840, 0, EA05f,
  189.     "PUBLIC",0,      0xFFFF, Public,
  190.     "REG",   0,      0xFFFF, Reg,
  191.     "RESET", 0x4E70, 0, 0,
  192.     "ROL",   0xE718, CntR911, 0,
  193.     "ROR",   0xE618, CntR911, 0,
  194.     "RORG",  0,      0xFFFF, Org,
  195.     "ROXL",  0xE510, CntR911, 0,
  196.     "ROXR",  0xE410, CntR911, 0,
  197.     "RTE",   0x4E73, 0, 0,
  198.     "RTR",   0x4E77, 0, 0,
  199.     "RTS",   0x4E75, 0, 0,
  200.     "SBCD",  0x8100, Rx911 | RegMem3 | Ry02, 0,
  201.     "SCC",   0x54C0, 0, EA05e,
  202.     "SCS",   0x55C0, 0, EA05e,
  203.     "SECTION", 0,    0xFFFF, Section,
  204.     "SEQ",   0x57C0, 0, EA05e,
  205.     "SET",   0,      0xFFFF, Set,
  206.     "SF",    0x51C0, 0, EA05e,
  207.     "SGE",   0x5CC0, 0, EA05e,
  208.     "SGT",   0x5EC0, 0, EA05e,
  209.     "SHI",   0x52C0, 0, EA05e,
  210.     "SLE",   0x5FC0, 0, EA05e,
  211.     "SLS",   0x53C0, 0, EA05e,
  212.     "SLT",   0x5DC0, 0, EA05e,
  213.     "SMI",   0x5BC0, 0, EA05e,
  214.     "SNE",   0x56C0, 0, EA05e,
  215.     "SPC",   0,      0xFFFF, Space,
  216.     "SPL",   0x5AC0, 0, EA05e,
  217.     "ST",    0x50C0, 0, EA05e,
  218.     "STOP",  0x4E72, 0, Exten,
  219.     "SUB",   0x9000, OpM68D, EA05y,
  220.     "SUBA",  0x9000, OpM68A, EA05a,
  221.     "SUBI",  0x0400, 0, Size67 | EA05e | Exten,
  222.     "SUBQ",  0x5100, Data911, Size67 | EA05d,
  223.     "SUBX",  0x9100, Rx911 | RegMem3 | Ry02, Size67,
  224.     "SVC",   0x58C0, 0, EA05e,
  225.     "SVS",   0x59C0, 0, EA05e,
  226.     "SWAP",  0x4840, Ry02, 0,
  227.     "TAS",   0x4AC0, 0, EA05e,
  228.     "TITLE", 0,      0xFFFF, Title,
  229.     "TRAP",  0x4E40, Data03, 0,
  230.     "TRAPV", 0x4E76, 0, 0,
  231.     "TST",   0x4A00, 0, Size67 | EA05e,
  232.     "UNLK",  0x4E58, Ry02, 0,
  233.     "XDEF",  0,      0xFFFF, Xdef,
  234.     "XREF",  0,      0xFFFF, Xref,
  235.     "",0,0,0};        /* End-of-table flag */
  236.  
  237.  
  238.  
  239.     if (maxinst == 0) {        /* Determine size of opcode table. */
  240.     while (MnemTab[maxinst].Mnem[0])
  241.         maxinst++;
  242.     limits[0] = 0;
  243.     limits['Z'-'A'+1] = maxinst;
  244.     mid = 0;
  245.     for (lower = 0; lower < maxinst; lower++) {
  246.         upper = (unsigned int) MnemTab[lower].Mnem[0] - 'A' + 1;
  247.         if (upper != mid) {
  248.         if (upper > 0) {    /* Start of the next letter */
  249.             mid++;
  250.             while (mid < upper)
  251.             limits[mid++] = lower;
  252.             limits[mid] = lower;
  253.         }
  254.         }
  255.     }
  256.     mid++;
  257.     while (mid < 'Z'-'A'+1) {
  258.         limits[mid++] = maxinst;    /* In case we didn't get to Z */
  259.     }
  260.     }
  261.     mid = (unsigned int) OpCode[0] - 'A' + 1;
  262.     if (mid < 0) {            /* This catches stuff like "=". */
  263.     lower = 0;
  264.     upper = limits[1];
  265.     } else if (mid > 'Z'-'A'+1) {
  266.     lower = upper = 0;        /* Reject this one. */
  267.     } else {
  268.     lower = limits[mid++];
  269.     upper = limits[mid];
  270.     }
  271.     while (lower < upper) {
  272.     mid = (lower + upper) / 2;    /* Search the opcode table. */
  273.     for (i = OpCode, j = MnemTab[mid].Mnem; *i == *j; i++, j++)
  274.         if (*i == '\0')
  275.         break;        /* Find the first non-match. */
  276.     if (*i < *j)
  277.         upper = mid;    /* Search lower half of table. */
  278.     else if (*i > *j)
  279.         lower = mid + 1;    /* Search upper half of table. */
  280.     else if (MnemTab[mid].AMA != 0xFFFF) {    /* Found it. */
  281.         Op = MnemTab[mid].OpBits;    /* Executable instruction */
  282.         AdrModeA = MnemTab[mid].AMA;
  283.         AdrModeB = MnemTab[mid].AMB;
  284.         Dir = None;
  285.         return (TRUE);
  286.     } else {
  287.         Op = AdrModeA = AdrModeB = 0;    /* Directive */
  288.         Dir = MnemTab[mid].AMB;
  289.         return (TRUE);
  290.     }
  291.     }
  292.     Op = AdrModeA = AdrModeB = Dir = 0;
  293.     return (FALSE);            /* We didn't find it. */
  294. }
  295.